package com.mk.cloud.common.msg;

import act.Act;
import act.app.App;
import act.event.On;
import act.ws.WebSocketConnectionManager;
import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import com.alibaba.fastjson.JSON;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.mk.cloud.Application;
import com.mk.cloud.common.config.AppConfig;
import com.mk.cloud.common.domain.CpMsg;
import com.mk.cloud.common.domain.CpUser;
import com.mk.cloud.common.enums.GlobalValues;
import com.mk.cloud.common.msg.template.MsgTemplate;
import com.mk.cloud.common.service.core.WsService;
import com.mk.cloud.common.util.DateUtils;
import org.osgl.util.S;import com.mk.cloud.common.util.S2;
import com.taobao.api.ApiException;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.AlibabaAliqinFcSmsNumSendRequest;
import com.taobao.api.response.AlibabaAliqinFcSmsNumSendResponse;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.osgl.util.C;

import javax.inject.Singleton;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Singleton
@SuppressWarnings("unused")
public class MessageBus {
    private IAcsClient smsClient;
    private JPushClient appPushClient;

//    private String appkey = AppConfig.dayu.appkey.get();
//    private String appsecret = AppConfig.dayu.appsecret.get();
//    private String path = AppConfig.dayu.path.get();
//    private String title = AppConfig.dayu.title.get();
    private TaobaoClient client;

    private synchronized IAcsClient getSmsClient() {
        if (smsClient == null) {
            IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", AppConfig.dayu.appkey.get(), AppConfig.dayu.appsecret.get());
            try {
                DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", "Dysmsapi", "dysmsapi.aliyuncs.com");
            } catch (ClientException e) {
                e.printStackTrace();
            }
            smsClient = new DefaultAcsClient(profile);
        }
        return smsClient;
    }

    private synchronized JPushClient getAppPushClient() {
        if (appPushClient == null)
            appPushClient = new JPushClient(AppConfig.jiguang.masterSecret.get(), AppConfig.jiguang.appKey.get());
        return appPushClient;
    }

    private synchronized TaobaoClient getClient(){
        if (client == null)  client = new DefaultTaobaoClient(AppConfig.dayu.path.get(), AppConfig.dayu.appkey.get(), AppConfig.dayu.appsecret.get());
        return client;
    }

    private void sms(CpMsg msMsg) {
        if (StringUtils.isNotBlank(msMsg.getPhone())) {
            String phone = S2.replaceReg(msMsg.getPhone(), "[a-zA-Z]", "");
            AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest();
            req.setSmsType("normal");
            req.setSmsFreeSignName(AppConfig.dayu.title.get());

            Map params = JSON.parseObject(msMsg.getWparams());
            if (StringUtils.equals(GlobalValues.FLAG_1.value(), MapUtils.getString(params, "nosms"))) return;
            Map newParam = new HashMap();

            for (Object o : msMsg.getParams().entrySet()) {
                Map.Entry entry = (Map.Entry) o;
                if (entry.getValue() != null) {
                    String v = entry.getValue().toString();
                    if (v.length() > 15) {
                        newParam.put(entry.getKey(), v.substring(v.length() - 15));
                    } else {
                        newParam.put(entry.getKey(), v);
                    }
                }
            }
            req.setSmsParamString(JSON.toJSONString(newParam));
            req.setRecNum(phone);
            req.setSmsTemplateCode(MapUtils.getString(msMsg.getParams(),"sms_code"));
            try {
                TaobaoClient c = getClient();
                AlibabaAliqinFcSmsNumSendResponse rsp = c.execute(req);
                System.out.println(rsp.getBody());
            } catch (ApiException e) {
                e.printStackTrace();
            }
        }
    }

    private void appPush(CpMsg msMsg) {
        PushPayload payload = PushPayload
            .newBuilder()
            .setPlatform(Platform.all())
            .setAudience(Audience.alias(Act.mode().toString() + msMsg.getUserid()))
            .setOptions(Options.newBuilder()
                .setApnsProduction(StringUtils.equals(AppConfig.jiguang.product.get(), GlobalValues.COMMON_1.value()))
                .build())
            .setMessage(cn.jpush.api.push.model.Message
                .newBuilder()
                .addExtras(msMsg.getParams())
                .setMsgContent(msMsg.getMsg())
                .setTitle(msMsg.getTitle())
                .setContentType(msMsg.getMtype())
                .build())
            .build();
        try {
            Application.LOG.info(JSON.toJSONString(getAppPushClient().sendPush(payload)));
        } catch (APIConnectionException | APIRequestException e) {
            e.printStackTrace();
        }
    }

    private void webPush(CpMsg msMsg){
        WsService.handleNewsUpdate(msMsg);

    }

    @On(value = "message-send", async = true)
    public void send(MsgTemplate template) {
        Map<String, String> params = template.params();
        if (params == null) params = new HashMap<>();
        String sms_code = template._sms_code();
        if (S.isNotBlank(sms_code)) params.put("sms_code", sms_code);


        CpMsg cpMsg = new CpMsg();
        cpMsg.setTitle(S2.stringBuild(template.title(), params));
        cpMsg.setMtime(DateUtils.formatTimeNow(DateUtils.DEFAULT_TIME_FORMAT));
        cpMsg.setMstate(GlobalValues.MSSTATE_0.value());
        cpMsg.setMsg(S2.stringBuild(template.msg(), params));
        cpMsg.setMtype(template._mtype());
        cpMsg.setMurl(S2.stringBuild(template.murl(), params));
        cpMsg.setPic(template.pic());
        cpMsg.setParams(params);

        int channel = template._channels();
        Set<String> phone = template.phones();
        Set<String> userid = template.userids();
        Set<String> usertype = template.usertypes();
        App app = App.instance();

        CpUser.Mapper mapper = app.getInstance(CpUser.Mapper.class);
        CpMsg.Mapper msMapper = app.getInstance(CpMsg.Mapper.class);
        //纯短信、针对系统外部人员
        if (MsgTemplate.MessChannel.SMS.isEnabled(channel) && C.notEmpty(phone)) {
            phone.forEach(p -> {
                CpMsg m = new CpMsg(cpMsg);
                m.setPhone(p);
                sms(m);
            });
        }
        //ps用户过滤条件
        Map<String, Object> ps = new HashMap<>();
        if (C.notEmpty(userid))
            ps.put("userid", userid);
        if (C.notEmpty(usertype))
            ps.put("usertype", template.usertypes());
        if (C.notEmpty(ps)) {
            List<Map> us = mapper.getSQLManager().select("user.select_contact", Map.class, ps);
            us.forEach(u -> {
                CpMsg m = new CpMsg(cpMsg);
                m.setUserid(MapUtils.getString(u, "userid"));
                m.setPhone(MapUtils.getString(u, "phone"));
                if (template._save()) msMapper.insertTemplate(m, true);
                else m.setMid("0");
                if (MsgTemplate.MessChannel.SMS.isEnabled(channel) && (C.empty(phone) || C.notEmpty(phone) && phone.add(m.getPhone())))
                    sms(m);
                if (MsgTemplate.MessChannel.APP.isEnabled(channel))
                    appPush(m);
                if(MsgTemplate.MessChannel.WEB.isEnabled(channel))
                    webPush(m);
            });
        }
    }
}